/*I2S routines*/
#ifndef I2S_H
#define I2S_H

/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"

/*Header File*/
#include "..\common\errcode.h"
#include "..\common\osdata.h"

/*Device specific headers*/
#include <AT91SAM7S64.H>
#include <lib_AT91SAM7S64.h>

/*Configurations*/
#define I2S_SENDRCV_DIS_W_SETTING   0 //The I2S PDC is temporarily disabled while configuring to send / receive

/*Definitions*/

#define rxEnable rxEnabled
#define txEnable txEnabled

/*IO Ports definition*/

/*enumerations*/
//Error codes for I2S initialization
typedef enum
{
	i2sInitSuccess = 0,
} eI2sInitError;

/*Types Definition, unions*/
#pragma anon_unions

typedef struct
{
    unsigned portLONG slotByFrame:3, bitsBySLot:6, samplingFreq:21, rxEnabled:1, txEnabled:1;
} tI2sConfig;

typedef struct
{
    tI2sConfig config;    
    struct {tOSData  mutex, event;} send, receive;
} tI2sData;

typedef struct
{
   tI2sConfig config;
} tI2sInitData, *pI2sInitData;

typedef struct
{
    unsigned portSHORT size;
    const unsigned portCHAR *data;
    portTickType xBlockTime;
} tI2sSendData, *pI2sSendData;

typedef struct
{
    unsigned portSHORT size;
    unsigned portCHAR *data;
    portTickType xBlockTime;
} tI2sReceiveData, *pI2sReceiveData;

/*Constants*/

/*Variable Definition*/
extern tI2sData xI2sData;

/*Functionality enabling*/

/*Public Functions and procedures Declaration*/
eI2sInitError eI2sInit( pI2sInitData data );
void vI2sClose( void );
unsigned portCHAR cReceiveFrame(pI2sReceiveData pData);
unsigned portCHAR cSendFrame(pI2sSendData pData);
void vI2sISR( void );
extern void vI2sISREntry( void ); //Interrupt entry point written in the assembler file I2sISR.s

/*Macro definitions*/
#define I2S_ASY_MASTER_TX_SETTING(nb_bit_by_slot, nb_slot_by_frame)( +\
AT91C_SSC_CKS_DIV +\
AT91C_SSC_CKO_CONTINOUS +\
AT91C_SSC_START_FALL_RF +\
((0 << 16) & AT91C_SSC_STTDLY) +\
((((nb_bit_by_slot * nb_slot_by_frame) / 2) - 1) << 24))
    
#define I2S_ASY_TX_FRAME_SETTING(nb_bit_by_slot, nb_slot_by_frame)( +\
(nb_bit_by_slot-1)  +\
AT91C_SSC_MSBF +\
(((nb_slot_by_frame - 1) << 8) & AT91C_SSC_DATNB) +\
(((nb_bit_by_slot - 1) << 16) & AT91C_SSC_FSLEN) +\
AT91C_SSC_FSOS_NEGATIVE)
#endif //I2S_H
